package com.buddy.java.thread.example;

import com.buddy.java.thread.tow_phase_termination.AbstractTerminatableThread;

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * 停止生产者-消费者中的线程例子
 */
public class SomeService {
    
    private final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(100);
    
    private final Producer producer = new Producer();
    private final Consumer consumer = new Consumer();
    private class Producer extends AbstractTerminatableThread {
        private int i = 0;
        protected void doRun() throws Exception {
            String product = String.valueOf(i++);
            queue.put(product);
            System.out.println("Producer product:"+product);
            consumer.terminationToken.reservations.incrementAndGet();
        }
    }

    private class Consumer extends AbstractTerminatableThread {
        protected void doRun() throws Exception {
            String product = queue.take();
            System.out.println("Consumer product:"+product);
            
            //模拟真正操作的时间消耗
            try{
                Thread.sleep(new Random().nextInt(100));
            }finally {
                terminationToken.reservations.decrementAndGet();
            }
        }
    }
    
    public void shutdown(){
        //生产者线程停止后,再停止消费者
        producer.terminate(true);
        consumer.terminate();
    }
    
    public void init(){
        producer.start();
        consumer.start();
    }
    
    public static void main(String[] args) throws InterruptedException {
        SomeService someService = new SomeService();
        someService.init();
        Thread.sleep(500);
        someService.shutdown();
    }
}
